<template>
  <el-container>
    <el-header>
      <div style="display: flex">
        <logo :height="60" />
        <div class="top-title">欢迎使用组态设计器</div>
        <div style="display: flex; align-items: center; margin-left: 20px">
          <el-button type="primary" @click="writeAllPageJson" size="small"
            >输出json</el-button
          >
        </div>
        <div style="display: flex; align-items: center; margin-left: 20px">
          <el-button type="primary" @click="restoreConfig" size="small"
            >加载配置</el-button
          >
        </div>
        <div style="display: flex; align-items: center; margin-left: 20px">
          <el-button
            type="primary"
            @click="addNewPage(currentEdit)"
            size="small"
          >
            添加页面
          </el-button>
        </div>
      </div>
    </el-header>
    <el-tabs
      v-model="currentEdit"
      type="card"
      @tab-remove="removePage"
      class="tab-pages"
    >
      <el-tab-pane
        v-for="page in pages"
        :key="page.id"
        :label="page.title"
        :name="page.name"
        :closable="page.closable"
      >
        <span slot="label">
          <span>{{ page.title }}</span>
          <i class="el-icon-edit" @click="handleEditTabLabel(page)"></i>
        </span>
        <div>
          {{ page.id }}
        </div>
        <x-stage :ref="`p_${page.id}`" :pages="pages" :current="page" />
      </el-tab-pane>
    </el-tabs>
    <el-dialog
      title="页面名称"
      :close-on-click-modal="false"
      :visible.sync="editLabelDialog.visible"
      width="30%"
    >
      <el-form ref="pageTitleForm" :model="editLabelDialog.form">
        <el-form-item
          label="页面名称"
          label-width="120px"
          prop="pageTitle"
          :rules="[
            { required: true, message: '请输入页面名称', trigger: 'change' },
          ]"
        >
          <el-input v-model="editLabelDialog.form.pageTitle"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editLabelDialog.visible = false">取 消</el-button>
        <el-button type="primary" @click="changeTabLabel">确 定</el-button>
      </div>
    </el-dialog>
  </el-container>
</template>
<script>
import Logo from "@/components/logo/Logo";
import XStage from "./XStage.vue";
import { UUID, downloadJSON } from "@/utils/index";
import _ from "lodash";
import { pageConfig } from "@/utils/schema";
import { Loading } from "element-ui";

export default {
  name: "Design",
  components: {
    Logo,
    XStage,
  },
  mounted () {
    //隐藏进入页面时的loading效果以适配vue加载之前的白屏
    let entryLoading = window.document.getElementById('entry-load');
    if (entryLoading) {
      entryLoading.style.display = "none";
    }

  },
  methods: {
    writeAllPageJson () {
      let _pages = _.cloneDeep(this.pages);
      for (let p of _pages) {
        p.stageConfig = this.$refs[`p_${p.id}`][0].getStageConfig();
      }
      console.log(JSON.stringify(_pages), "所有配置");
      downloadJSON(_pages);
    },
    //预加载某一张图片
    async loadImage (_src) {
      // eslint-disable-next-line no-unused-vars
      return new Promise((resolve, reject) => {
        const image = new window.Image();
        image.onload = () => {
          resolve();
        };
        image.onerror = () => {
          resolve();
        };
        image.src = _src;
      });
    },
    //预加载所有的图片
    async loadResources (_pages) {
      const imageUrlList = _.cloneDeep(
        _pages.map((p) =>
          p.stageConfig.list
            .filter((s) => s.xType === "x-image")
            .map((x_image) => x_image.src)
        )
      ).flat();
      console.log(imageUrlList, "待加载图片资源列表");
      //若资源中含有多于一张图片则显示加载图片的资源进度
      if (imageUrlList.length > 0) {
        let loading = Loading.service({
          lock: true,
          text: `正在加载资源_0/${imageUrlList.length}`,
          spinner: "el-icon-loading",
          background: "rgba(0, 0, 0, 0.7)",
        });
        let i = 0; //累加资源进度
        await Promise.all([
          ...imageUrlList.map((src) => {
            return this.loadImage(src).then(() => {
              i++;
              loading?.setText?.(`正在加载资源_${i}/${imageUrlList.length}`);
            });
          }),
        ]);
        loading.close();
      }
    },

    async loadAllPageJson (_pages) {
      this.pages = [];

      this.pages = _pages.map((p) => {
        return {
          title: p.title,
          name: p.name,
          closable: p.closable,
          id: p.id,
        };
      });
      window.setTimeout(() => {
        for (let p of _pages) {
          this.$refs[`p_${p.id}`][0].setStageConfig(_.cloneDeep(p.stageConfig));
        }
        this.currentEdit = "home";
      }, 0);

      //预加载所有的图片(放在此处是为了先把界面的骨架显示出来这样的话用户心里不会看到白屏从而感到慌张)
      await this.loadResources(_pages);
    },
    restoreConfig () {
      this.loadAllPageJson(pageConfig);
    },
    // eslint-disable-next-line no-unused-vars
    addNewPage (targetName) {
      let newId = UUID();
      this.pages.push({
        title: `新页面 ${++this.pageIndex}`,
        name: newId,
        closable: true,
        id: newId,
      });
      this.currentEdit = newId;
    },
    removePage (targetName) {
      let tabs = this.pages;
      let activeName = this.currentEdit;
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1];
            if (nextTab) {
              activeName = nextTab.name;
            }
          }
        });
      }
      this.currentEdit = activeName;
      this.pages = tabs.filter((tab) => tab.name !== targetName);
    },
    handleEditTabLabel (p) {
      console.log("编辑");
      this.editLabelDialog.visible = true;
      this.editLabelDialog.id = p.id;
      this.editLabelDialog.form.pageTitle = p.title;
    },
    changeTabLabel () {
      this.$refs["pageTitleForm"].validate((valid) => {
        console.log(valid, "验证情况");
        if (valid) {
          let p = this.pages.find((p) => p.id === this.editLabelDialog.id);
          if (p) {
            p.title = this.editLabelDialog.form.pageTitle;
          }
          this.editLabelDialog.visible = false;
          this.editLabelDialog.form.pageTitle = "";
        }
      });
    },
  },
  data () {
    return {
      editLabelDialog: {
        visible: false,
        form: {
          id: null,
          pageTitle: "",
        },
      },
      currentEdit: "home",
      pages: [
        {
          title: "首页",
          name: "home",
          closable: false,
          id: "home",
        },
      ],
      pageIndex: 1,
    };
  },
};
</script>

<style lang="scss" scoped>
$--color-text-placeholder: #c0c4cc;
$--color-white: #ffffff;

.top-title {
  height: 60px;
  line-height: 60px;
  margin-left: 50px;
  font-size: 20px;
  font-weight: bold;
}

.el-container {
  height: 100%;
}

.el-header {
  height: 50px;
  border-bottom: 1px solid #cccccc;
}

.tab-pages ::v-deep .el-tabs__content {
  position: static; //特别注意的这里的样式是为了解决内部的右键菜单position:absolute会根据父级的relative计算定位
  //原为relative 菜单会根据 此出来进行 绝对定位这就会产生错误,应该依据body进行定位才正确
}

//设置编辑(修改)按钮的样式
.tab-pages ::v-deep .el-tabs__item {
  .el-icon-edit {
    //参照ele源码段落1
    border-radius: 50%;
    text-align: center;
    transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
    margin-left: 5px;
    &:before {
      transform: scale(0.9);
      display: inline-block;
    }

    &:hover {
      background-color: $--color-text-placeholder;
      color: $--color-white;
    }

    //参照ele源码段落2
    position: relative;
    font-size: 12px;
    width: 0;
    height: 14px;
    vertical-align: middle;
    line-height: 15px;
    overflow: hidden;
    top: -1px;
    right: -2px;
    transform-origin: 100% 50%;
  }

  &:hover,
  &.is-active {
    .el-icon-edit {
      //参照ele源码似的移动上去后给出编辑i标签按钮宽度使得其hover时呈现出一种平缓的动画效果
      width: 14px;
    }
  }
}
</style>
